import { defineComponent, ref, computed, unref, reactive, watch, watchEffect } from 'vue';
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
import { useEventListener } from '/@/hooks/event/useEventListener';
import { basicProps } from './props';
import { getSlot } from '/@/utils/helper/tsxHelper';
import './DragVerify.less';
import { CheckOutlined, DoubleRightOutlined } from '@ant-design/icons-vue';
import { useExpose } from '/@/hooks/core/useExpose';
export default defineComponent({
    name: 'BaseDargVerify',
    props: basicProps,
    emits: ['success', 'update:value', 'change', 'start', 'move', 'end'],
    setup(props, { emit, slots }) {
        const state = reactive({
            isMoving: false,
            isPassing: false,
            moveDistance: 0,
            toLeft: false,
            startTime: 0,
            endTime: 0,
        });
        const wrapElRef = ref(null);
        const barElRef = ref(null);
        const contentElRef = ref(null);
        const actionElRef = ref(null);
        watch(() => state.isPassing, (isPassing) => {
            if (isPassing) {
                const { startTime, endTime } = state;
                const time = (endTime - startTime) / 1000;
                emit('success', { isPassing, time: time.toFixed(1) });
                emit('update:value', isPassing);
                emit('change', isPassing);
            }
        });
        watchEffect(() => {
            state.isPassing = !!props.value;
        });
        const getActionStyleRef = computed(() => {
            const { height, actionStyle } = props;
            const h = `${parseInt(height)}px`;
            return {
                left: 0,
                width: h,
                height: h,
                ...actionStyle,
            };
        });
        const getWrapStyleRef = computed(() => {
            const { height, width, circle, wrapStyle } = props;
            const h = parseInt(height);
            const w = `${parseInt(width)}px`;
            return {
                width: w,
                height: `${h}px`,
                lineHeight: `${h}px`,
                borderRadius: circle ? h / 2 + 'px' : 0,
                ...wrapStyle,
            };
        });
        const getBarStyleRef = computed(() => {
            const { height, circle, barStyle } = props;
            const h = parseInt(height);
            return {
                height: `${h}px`,
                borderRadius: circle ? h / 2 + 'px 0 0 ' + h / 2 + 'px' : 0,
                ...barStyle,
            };
        });
        const getContentStyleRef = computed(() => {
            const { height, width, contentStyle } = props;
            const h = `${parseInt(height)}px`;
            const w = `${parseInt(width)}px`;
            return {
                height: h,
                width: w,
                ...contentStyle,
            };
        });
        function getEventPageX(e) {
            return e.pageX || e.touches[0].pageX;
        }
        useEventListener({
            el: document,
            name: 'mouseup',
            listener: () => {
                if (state.isMoving) {
                    resume();
                }
            },
        });
        function handleDragStart(e) {
            if (state.isPassing) {
                return;
            }
            const actionEl = unref(actionElRef);
            if (!actionEl)
                return;
            emit('start', e);
            state.moveDistance = getEventPageX(e) - parseInt(actionEl.style.left.replace('px', ''), 10);
            state.startTime = new Date().getTime();
            state.isMoving = true;
        }
        function getOffset(el) {
            const actionWidth = parseInt(el.style.width);
            const { width } = props;
            const widthNum = parseInt(width);
            const offset = widthNum - actionWidth - 6;
            return { offset, widthNum, actionWidth };
        }
        function handleDragMoving(e) {
            const { isMoving, moveDistance } = state;
            if (isMoving) {
                const actionEl = unref(actionElRef);
                const barEl = unref(barElRef);
                if (!actionEl || !barEl)
                    return;
                const { offset, widthNum, actionWidth } = getOffset(actionEl);
                const moveX = getEventPageX(e) - moveDistance;
                emit('move', {
                    event: e,
                    moveDistance,
                    moveX,
                });
                if (moveX > 0 && moveX <= offset) {
                    actionEl.style.left = `${moveX}px`;
                    barEl.style.width = `${moveX + actionWidth / 2}px`;
                }
                else if (moveX > offset) {
                    actionEl.style.left = `${widthNum - actionWidth}px`;
                    barEl.style.width = `${widthNum - actionWidth / 2}px`;
                    if (!props.isSlot) {
                        checkPass();
                    }
                }
            }
        }
        function handleDragOver(e) {
            const { isMoving, isPassing, moveDistance } = state;
            if (isMoving && !isPassing) {
                emit('end', e);
                const actionEl = unref(actionElRef);
                const barEl = unref(barElRef);
                if (!actionEl || !barEl)
                    return;
                const moveX = getEventPageX(e) - moveDistance;
                const { offset, widthNum, actionWidth } = getOffset(actionEl);
                if (moveX < offset) {
                    if (!props.isSlot) {
                        resume();
                    }
                    else {
                        setTimeout(() => {
                            if (!props.value) {
                                resume();
                            }
                            else {
                                const contentEl = unref(contentElRef);
                                if (contentEl) {
                                    contentEl.style.width = `${parseInt(barEl.style.width)}px`;
                                }
                            }
                        }, 0);
                    }
                }
                else {
                    actionEl.style.left = `${widthNum - actionWidth}px`;
                    barEl.style.width = `${widthNum - actionWidth / 2}px`;
                    checkPass();
                }
                state.isMoving = false;
            }
        }
        function checkPass() {
            if (props.isSlot) {
                resume();
                return;
            }
            state.endTime = new Date().getTime();
            state.isPassing = true;
            state.isMoving = false;
        }
        function resume() {
            state.isMoving = false;
            state.isPassing = false;
            state.moveDistance = 0;
            state.toLeft = false;
            state.startTime = 0;
            state.endTime = 0;
            const actionEl = unref(actionElRef);
            const barEl = unref(barElRef);
            const contentEl = unref(contentElRef);
            if (!actionEl || !barEl || !contentEl)
                return;
            state.toLeft = true;
            useTimeoutFn(() => {
                state.toLeft = false;
                actionEl.style.left = '0';
                barEl.style.width = '0';
                //  The time is consistent with the animation time
            }, 300);
            contentEl.style.width = unref(getContentStyleRef).width;
        }
        useExpose({
            resume,
        });
        return () => {
            const renderBar = () => {
                const cls = [`darg-verify-bar`];
                if (state.toLeft) {
                    cls.push('to-left');
                }
                return <div class={cls} ref={barElRef} style={unref(getBarStyleRef)}/>;
            };
            const renderContent = () => {
                const cls = [`darg-verify-content`];
                const { isPassing } = state;
                const { text, successText } = props;
                isPassing && cls.push('success');
                return (<div class={cls} ref={contentElRef} style={unref(getContentStyleRef)}>
            {getSlot(slots, 'text', isPassing) || (isPassing ? successText : text)}
          </div>);
            };
            const renderAction = () => {
                const cls = [`darg-verify-action`];
                const { toLeft, isPassing } = state;
                if (toLeft) {
                    cls.push('to-left');
                }
                return (<div class={cls} onMousedown={handleDragStart} onTouchstart={handleDragStart} style={unref(getActionStyleRef)} ref={actionElRef}>
            {getSlot(slots, 'actionIcon', isPassing) ||
                        (isPassing ? (<CheckOutlined class={`darg-verify-action__icon`}/>) : (<DoubleRightOutlined class={`darg-verify-action__icon`}/>))}
          </div>);
            };
            return (<div class="darg-verify" ref={wrapElRef} style={unref(getWrapStyleRef)} onMousemove={handleDragMoving} onTouchmove={handleDragMoving} onMouseleave={handleDragOver} onMouseup={handleDragOver} onTouchend={handleDragOver}>
          {renderBar()}
          {renderContent()}
          {renderAction()}
        </div>);
        };
    },
});
//# sourceMappingURL=DragVerify.jsx.map